﻿using System.Linq;
using FNN.Networks;
using System;

namespace FNN.Genetic
{
    public class DnaHelix
    {
        /// <summary>
        ///     Конструктор на основе цепочек
        /// </summary>
        /// <param name="synapsesChain">Цепочка синапсов</param>
        /// <param name="layersChain">Цепочка слоев</param>
        public DnaHelix(string synapsesChain, string layersChain)
        {
            SynapsesChain = synapsesChain;
            LayersChain = layersChain;
        }

        /// <summary>
        ///     Конструктор на основе структуры сети
        /// </summary>
        /// <param name="targetStructure">Целевая структура</param>
        public DnaHelix(NetworkStructure targetStructure)
        {
            LayersChain = String.Join("|", targetStructure.LayerStructures.ToList().Select(o => String.Join(";", o.FunctionsList)));
            SynapsesChain = String.Join("|", targetStructure.SynapseStructures.ToList().Select(o => o.InputNeuronId.ToString() + ";" + o.OutputNeuronId.ToString()));
        }

        /// <summary>
        ///     Конструктор по умолчанию
        /// </summary>
        public DnaHelix()
        {
            SynapsesChain = "";
            LayersChain = "";
        }

        /// <summary>
        ///     Цепочка синапсов
        /// </summary>
        public string SynapsesChain { get; set; }

        /// <summary>
        ///     Цепочка слоев
        /// </summary>
        public string LayersChain { get; set; }

        /// <summary>
        ///     Получить структуру сети
        /// </summary>
        /// <returns></returns>
        public NetworkStructure GetNetworkStructure()
        {
            var result = new NetworkStructure();
            var synapsesArray = SynapsesChain.Split('|');
            var layersArray = LayersChain.Split('|');

            result.SynapseStructures = new SynapseStructure[synapsesArray.Length];
            for (var i = 0; i < synapsesArray.Length; i++)
            {
                result.SynapseStructures[i] = new SynapseStructure(synapsesArray[i]);
            }

            result.LayerStructures = new LayerStructure[layersArray.Length];
            for (var i = 0; i < layersArray.Length; i++)
            {
                result.LayerStructures[i] = new LayerStructure(layersArray[i]);
            }

            return result;
        }

        /// <summary>
        ///     Извлечь структуру сети
        /// </summary>
        /// <param name="target">Целевая сеть</param>
        public void ParseNetwork(Network target)
        {
            LayersChain =
                string.Join("|", target.Layers.Select(
                    layer => string.Join(";", layer.Neurons.Select(o => Convert.ToInt32(o.NeuronFunctionId).ToString()).ToArray()))
                    .ToList());

            SynapsesChain = string.Join("|",
                target.Synapses.Select(o => o.InputNeuron.NeuronId + ";" + o.OutputNeuron.NeuronId + ";" +
                                            o.Weight).ToList());
        }
    }
}